<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>画廊-首页展示</title>
</head>

<body>
  <div id="mountNode"></div>
  <p>数据来源：http://sigmajs.org/assets/data/les-miserables.json</p>
  <p>描述：数据含义暂时未知，用于艺术展示</p>
  <script src="./assets/jquery-3.2.1.min.js"></script>
  <script src="./assets/d3-4.13.0.min.js"></script>
  <script src="./assets/d3-legend-2.25.6.min.js"></script>
  <script src="../build/g6.js"></script>
  <script src="../build/plugin.layout.circle.js"></script>
  <script src="../build/plugin.layout.dagre.js"></script>
  <script src="../build/plugin.layout.grid.js"></script>
  <script src="../build/plugin.layout.archimeddeanSpiral.js"></script>
  <script src="../build/plugin.tool.d3.mapper.js"></script>
  <script src="../build/plugin.template.maxSpanningForest.js"></script>
  <script src="https://gw.alipayobjects.com/os/antv/assets/lib/d3-4.13.0.min.js"></script>
  <script>
    $.getJSON('./assets/data/g6-index.json', data => {
      const { forceSimulation, forceLink, forceManyBody, forceCenter, forceCollide } = d3;
      const Template = G6.Plugins['template.maxSpanningForest'];
      const Mapper = G6.Plugins['tool.d3.mapper'];
      const nodeSizeMapper = new Mapper('node', 'weight', 'size', [8, 20], {
        legendCfg: null
      });
      const edgeSizeMapper = new Mapper('edge', 'weight', 'size', [1, 8], {
        legendCfg: null
      });
      const nodeColorMapper = new Mapper('node', 'weight', 'color', ['#E0F5FF', '#BAE7FF', '#91D5FF', '#69C0FF', '#3DA0F2', '#1581E6', '#0860BF'], {
        legendCfg: null
      });
      const force = {
        execute() {
          const nodes = this.nodes;
          const edges = this.edges;
          const graph = this.graph;
          const width = graph.getWidth();
          const height = graph.getHeight();
          const simulation = forceSimulation(nodes)
          .force('charge', forceManyBody().distanceMax(width * 3))
          .force('link', forceLink(G6.Util.cloneDeep(edges))
            .id(model => {
              return model.id;
            })
            .strength(1)
          )
          .force('center', forceCenter(width / 2, height / 2))
          .force('collision', forceCollide().radius(model => {
            return model.width / 2 * 1.2;
          }));
          simulation.stop();
          for (let i = 0, n = Math.ceil(Math.log(simulation.alphaMin()) / Math.log(1 - simulation.alphaDecay())); i < n; ++i) {
            simulation.tick();
          }
          nodes.forEach(node => {
            delete node.vx;
            delete node.vy;
          });
        }
      };
      const template = new Template({
        fisheye: false,
        interactive: false,
        textDisplay: false,
        node_label: null,
        edgeStyle(model) {
          return {
            stroke: graph.find(model.target).getModel().color,
            strokeOpacity: 0.8
          };
        }
      });
      const graph = new G6.Graph({
        id: 'mountNode',             // dom id
        height: window.innerHeight,
        layout: {
          processer: force
        },
        plugins: [template, nodeSizeMapper, nodeColorMapper, edgeSizeMapper],
        animate: true,
      });
      const circle = new G6.Layouts['Circle']({
        sort(a, b) {
          return a.weight - b.weight;
        }
      });
      const grid = new G6.Layouts['Grid']({
        sort(a, b) {
          return b.weight - a.weight;
        }
      });
      const dagre = new G6.Layouts['Dagre']({
        nodesep() {
          return graph.getWidth() / 50;
        },
        ranksep() {
          return graph.getHeight() / 25;
        },
        marginx() {
          return graph.getWidth() / 8;
        },
        marginy() {
          return graph.getHeight() / 8;
        },
        useEdgeControlPoint: false,
      });
      const spiral = new G6.Layouts['ArchimeddeanSpiral']({
        sort(a, b) {
          return b.weight - a.weight;
        }
      });
      graph.read(data);
      setInterval(() => {
        if (document.visibilityState === 'visible') {
          let layouts = [circle, dagre, force, grid, spiral];
          layouts = layouts.filter(layout => {
            return layout !== graph.getLayout();
          });
          const layout = layouts[parseInt(layouts.length * Math.random())];
          graph.changeLayout(layout);
        }
      }, 2000);
    });
  </script>
</body>
</html>
